/*******************************************************************************
 * Package: com.hngtrust.iir.privatereport.controller
 * Type:    PrivateReportController
 * Date:    2021/9/14 10:27
 *
 * Copyright (c) 2021 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.hngtrust.iir.report.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hngtrust.framework.bind.ResponseInfo;
import com.hngtrust.framework.id.service.MyIdGenerator;
import com.hngtrust.framework.page.PageResult;
import com.hngtrust.framework.page.service.PageService;
import com.hngtrust.framework.security.util.SecurityUtils;
import com.hngtrust.iir.base.entity.Dict;
import com.hngtrust.iir.base.service.DictService;
import com.hngtrust.iir.base.service.IndustrySwService;
import com.hngtrust.iir.base.service.ReportTypeService;
import com.hngtrust.iir.dto.ReqDTO;
import com.hngtrust.iir.report.controller.dto.*;
import com.hngtrust.iir.report.dto.CountOrgVO;
import com.hngtrust.iir.report.dto.CountResearcherVO;
import com.hngtrust.iir.report.dto.CountUser;
import com.hngtrust.iir.report.dto.ReportRightDTO;
import com.hngtrust.iir.report.entity.PrivateReport;
import com.hngtrust.iir.report.entity.ReportCollect;
import com.hngtrust.iir.report.entity.ReportLog;
import com.hngtrust.iir.report.entity.ReportRight;
import com.hngtrust.iir.report.service.*;
import com.hngtrust.iir.user.entity.User;
import com.hngtrust.iir.util.DateUtils;
import com.hngtrust.iir.util.FileUtils;
import com.tiger.util.MyHttpClient;
import com.tiger.web.annotation.UploadMapping;
import com.tiger.web.service.FileService;
import com.zhuozhengsoft.pageoffice.OpenModeType;
import com.zhuozhengsoft.pageoffice.PageOfficeCtrl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.UUID;

/**
 * 内部研报controller
 *
 * @author Keqiwei
 * @date 2021/9/14 10:27
 */
@Slf4j
@RestController
@RequestMapping("/private-report")
@Api(tags = "内部研报")
public class ReportPrivateController {

    @Value("${ai.selfPrivateReport.url}")
    private String aiUrl;

    @Value("${upload.report.minio}")
    private String minioUpload;

    @Value("${pageoffice.posyspath}")
    private String poSysPath;

    @Value("${tiger.minio.out.address}")
    private String url;

    //文件路径
    @Value("${elk.search.url}")
    private String elkUrl;

    //minio地址
    @Value("${tiger.minio.out.address}")
    private String minioAddress;

    @Autowired
    @Qualifier("minIoFileService")
    private FileService fileService;

    @Autowired
    private ReportService reportService;

    @Autowired
    private MyIdGenerator myIdGenerator;

    @Autowired
    private PrivateReportService privateReportService;

    @Autowired
    private ReportRightBacService reportRightBacService;

    @Autowired
    private PageService pageService;


    @Autowired
    private ReportTypeService reportTypeService;

    @Autowired
    private ReportRightService reportRightService;

    @Autowired
    private DictService dictService;

    @Autowired
    private ReportCollectService collectService;

    @Autowired
    private ReportLogService reportLogService;

    @Autowired
    private IndustrySwService industrySwService;

    @ApiOperation(value = "上传研报")
    @UploadMapping("/upload-report")
    public ResponseInfo<UploadRespVO> uploadReport(@ApiParam("上传参数") @RequestParam(required = true) MultipartFile file) {
        try {
            long start = System.currentTimeMillis();
            MyHttpClient client = new MyHttpClient();
            ObjectMapper objectMapper = new ObjectMapper();
            String path = minioUpload + DateUtils.getTodayString() + "/";
            String directory = System.getProperty("java.io.tmpdir");
            User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();

            String substring = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String fileName = loginUser.getId().toString() + substring;
            File tempFile = new File(directory, fileName);
            file.transferTo(tempFile);//保存文件
            String retPath = fileService.upload(tempFile, path, true);
            long size = file.getSize();

            System.out.println(System.currentTimeMillis() - start);

            UploadReportAIReqDTO bo = new UploadReportAIReqDTO();
            bo.setPathString(retPath);
            String s = client.postJson(aiUrl, bo);

            System.out.println(System.currentTimeMillis() - start);


            JsonNode jsonNode = objectMapper.readTree(s);
            JsonNode data = jsonNode.get("data");
            UploadRespVO vo = objectMapper.readValue(data.toString(), UploadRespVO.class);
            if (vo.getReportType() != null) {
                String t = "";
                if (!StringUtil.isBlank(vo.getPublishOrg())) {
                    t = "【" + vo.getPublishOrg() + "】";
                }
                if (vo.getReportType() < 8 && vo.getReportType() > 1) {
                    String i = "";
                    if (vo.getReportIndustry() != null) {
                        i = industrySwService.queryByCode(vo.getReportIndustry()).getName() + "行业研报";
                    }
                    vo.setTitle(t + " " + i + " ：" + vo.getViewpoint());
                } else {

                    vo.setTitle(t + " " + vo.getEntityName() + " ：" + vo.getViewpoint());
                }
            }
            vo.setSize(size);
            vo.setFileName(file.getOriginalFilename());

            vo.setFilePath(retPath);
            if (vo.getReportType() != null) {
                vo.setReportTypeName(reportTypeService.queryById(vo.getReportType()).getName());
            }
            Map<String, Dict> reportLevel = dictService.queryDict("REPORT_LEVEL");
            Map<String, Dict> rankChange = dictService.queryDict("LEVEL_CHANGE");
            if (vo.getReportRank() != null) {
                vo.setRankName(dictService.queryDictByCode(reportLevel, vo.getReportRank().toString()).getBusiName());
            }
            if (vo.getRankChange() != null) {
                vo.setRankChangeName(dictService.queryDictByCode(rankChange, vo.getRankChange().toString()).getBusiName());
            }

            if (vo.getReportIndustry() != null) {
                vo.setReportIndustryName(industrySwService.queryByCode(vo.getReportIndustry()).getName());

            }

            System.out.println(System.currentTimeMillis() - start);

            return new ResponseInfo(vo);
        } catch (Exception e) {
            e.printStackTrace();
            ResponseInfo info = new ResponseInfo();
            info.setCode("1");
            info.setMessage("上传失败");
            return info;
        }
    }


    @ApiOperation(value = "保存研报")
    @PostMapping("/save-report")
    public ResponseInfo<String> saveReport(@ApiParam("请求参数") @RequestBody SavePrivateReportReqVO vo) {
        PrivateReport report = new PrivateReport();
        vo.setId(myIdGenerator.nextId());
        if (vo.getRightTag() == 2) {
            ReportRightVO vo1 = new ReportRightVO();
            vo1.setReportId(vo.getId());
            vo1.setUserId(vo.getUserIds());
            reportRightBacService.addRight(vo1);

        }
        if (vo.getPages() == null) {
            report.setPages(0);
        }
        BeanUtils.copyProperties(vo, report);
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        report.setCreateTime(new Date());
        report.setCreateUserId(loginUser.getId());
        report.setUpdateTime(new Date());

        report.setUpdateUserId(loginUser.getId());
        report.setComments(0);
        if (vo.getPublishTime() != null) {
            report.setPublishtime(new Date(vo.getPublishTime()));
        }
        report.setFileSize(vo.getSize());
        report.setLevelChange(vo.getRankChange());
        report.setReportLevel(vo.getRank());
        if (vo.getFileName().endsWith(".pdf") || vo.getFileName().endsWith(".xls") || vo.getFileName().endsWith(".xlsx") || report.getFileName().endsWith(".xlsm")) {
            report.setPdfPath(vo.getFilePath());
            reportService.createPrivateReport(report);
        }
        report.setIndustryId(industrySwService.queryByCode(vo.getIndustryCode()).getId());
        report.setStatus(0);
        if (report.getFileName().endsWith(".pdf"))
            report.setFileType(1);
        if (report.getFileName().endsWith(".xlsx") || report.getFileName().endsWith(".xlsm") || report.getFileName().endsWith(".xls"))
            report.setFileType(2);
        if (report.getFileName().endsWith(".doc") || report.getFileName().endsWith(".docx"))
            report.setFileType(3);
        privateReportService.add(report);
        ReportLog log = new ReportLog();
        log.setId(myIdGenerator.nextId());
        Date date = new Date();
        log.setCreateTime(date);
        log.setCreateTimeDt(DateUtils.format(date, DateUtils.DATETIME));
        log.setCreateUserId(loginUser.getId());
        log.setOptType("上传文件");
        log.setTitle(report.getTitle());
        log.setReportId(report.getId());
        reportLogService.add(log);
        return new ResponseInfo();
    }

    @ApiOperation(value = "修改前查询研报")
    @PostMapping("/update-select-report")
    public ResponseInfo<UpdatePrivateReportResqVO> updateSelectReport(@ApiParam("请求参数") @RequestBody SavePrivateReportReqVO vo) {

        PrivateReport privateReport = privateReportService.queryById(vo.getId());
        UpdatePrivateReportResqVO updatePrivateReportResqVO = new UpdatePrivateReportResqVO();
        BeanUtils.copyProperties(privateReport, updatePrivateReportResqVO);
        updatePrivateReportResqVO.setPublishTime(privateReport.getPublishtime().getTime());
        updatePrivateReportResqVO.setRank(privateReport.getReportLevel());
        updatePrivateReportResqVO.setRankChange(privateReport.getLevelChange());
        ReportRight reportRight = new ReportRight();
        reportRight.setReportId(vo.getId());
        List<ReportRightDTO> list = reportRightService.queryReportRights(reportRight);
        List<Long> userIdList = new ArrayList<>();
        if(list.size() > 0){
            for (int i = 0; i < list.size(); i++) {
                userIdList.add(list.get(i).getUserId());
            }
          updatePrivateReportResqVO.setUserIds(userIdList);
        }

        return new ResponseInfo<>(updatePrivateReportResqVO);
    }

    @ApiOperation(value = "修改研报")
    @PostMapping("/update-report")
    public ResponseInfo<String> updateReport(@ApiParam("请求参数") @RequestBody SavePrivateReportReqVO vo) {
        PrivateReport report = new PrivateReport();
        report.setId(vo.getId());
        Long reportId = vo.getId();
        //先根据研报id删除数据
        reportRightService.deleteRightByReportId(reportId);
        List<ReportRight> reportRights = new ArrayList<>();
        List<Long> userId = vo.getUserIds();
        //新增所有数据
        if (userId != null && userId.size() > 0) {
            for (Long aLong : userId) {
                ReportRight reportRight = new ReportRight();
                reportRight.setId(myIdGenerator.nextId());
                reportRight.setReportId(vo.getId());
                reportRight.setUserId(aLong);
                reportRight.setCreateTime(new Date());
                User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
                reportRight.setCreateUserId(loginUser.getId());
                reportRights.add(reportRight);
            }
            reportRightService.addRightByReportId(reportRights);
        }

        if (vo.getPages() == null) {
            report.setPages(0);
        }
        BeanUtils.copyProperties(vo, report);
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        report.setUpdateTime(new Date());
        report.setUpdateUserId(loginUser.getId());
        report.setComments(0);
        if (vo.getPublishTime() != null) {
            report.setPublishtime(new Date(vo.getPublishTime()));
        }

        report.setFileSize(vo.getSize());
        report.setLevelChange(vo.getRankChange());
        report.setReportLevel(vo.getRank());
        report.setRightTag(vo.getRightTag());
        report.setDwonTag(vo.getDwonTag());
        report.setIndustryId(industrySwService.queryByCode(vo.getIndustryCode()).getId());
        report.setStatus(0);
        if (report.getFileName().endsWith(".pdf"))
            report.setFileType(1);
        if (report.getFileName().endsWith(".xlsx") || report.getFileName().endsWith(".xlsm") || report.getFileName().endsWith(".xls"))
            report.setFileType(2);
        if (report.getFileName().endsWith(".doc") || report.getFileName().endsWith(".docx"))
            report.setFileType(3);
        privateReportService.modifyById(report);

        //修改elk数据
        reportService.updateElkReport(vo);

        ReportLog log = new ReportLog();
        log.setId(myIdGenerator.nextId());
        Date date = new Date();
        log.setCreateTime(date);
        log.setCreateTimeDt(DateUtils.format(date, DateUtils.DATETIME));
        log.setCreateUserId(loginUser.getId());
        log.setOptType("修改研报");
        log.setTitle(report.getTitle());
        log.setReportId(report.getId());
        reportLogService.add(log);
        return new ResponseInfo();
    }

    @ApiOperation(value = "删除研报")
    @PostMapping("/delete-update-report")
    public ResponseInfo<String> deleteUpdateReport(@ApiParam("请求参数") @RequestBody SavePrivateReportReqVO vo) {
        PrivateReport report = privateReportService.queryById(vo.getId());
        report.setId(vo.getId());

        privateReportService.updateDelete(report.getId());



        //修改elk数据
        reportService.deleteUpdateElkReport(vo);

        ReportLog log = new ReportLog();
        log.setId(myIdGenerator.nextId());
        Date date = new Date();
        log.setCreateTime(date);
        log.setCreateTimeDt(DateUtils.format(date, DateUtils.DATETIME));
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        log.setCreateUserId(loginUser.getId());
        log.setOptType("删除研报");
        log.setTitle(report.getTitle());
        log.setReportId(report.getId());
        reportLogService.add(log);
        return new ResponseInfo();
    }


    @ApiOperation("分析师")
    @PostMapping("/researcher")
    public ResponseInfo<List<CountResearcherVO>> researcher() {
        List<CountResearcherVO> l = privateReportService.countResearcher();
        if (l.isEmpty()) {

        } else {
            l = l.stream().sorted((a, b) -> -a.getCount().compareTo(b.getCount())).collect(Collectors.toList());

        }
        return new ResponseInfo(l);
    }

    @ApiOperation("机构")
    @PostMapping("/org")
    public ResponseInfo org() {
        List<CountOrgVO> countOrgVOS = privateReportService.countOrg();
        if (countOrgVOS.isEmpty()) {

        } else {
            countOrgVOS = countOrgVOS.stream().sorted((a, b) -> -a.getCount().compareTo(b.getCount())).collect(Collectors.toList());

        }

        return new ResponseInfo(countOrgVOS);
    }

    @ApiOperation("上传研报列表")
    @PostMapping("/list-upload")
    public ResponseInfo<PageResult<ListUploadVO>> listUpload(@ApiParam("请求参数") @RequestBody ReqDTO<PrivateUploadVO> vo) {
        PrivateReport report = new PrivateReport();
        String name;
        if (!StringUtil.isBlank(vo.getContent().getName())) {
            name = "%" + vo.getContent().getName() + "%";
        } else {
            name = null;
        }
        report.setFileName(vo.getContent().getName());
        Integer i;

        if (vo.getContent().getStatus() != 0) {
            i = vo.getContent().getStatus();
        } else {
            i = null;
        }

        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        report.setCreateUserId(loginUser.getId());
        PageResult<PrivateReport> page = pageService.page(vo.getPageParam(), () -> privateReportService.query(name, i, loginUser.getId()));
        PageResult<ListUploadVO> pageResult = new PageResult<>();
        pageResult.setPage(page.getPage());
        List<ListUploadVO> list = new ArrayList<>();
        for (PrivateReport p : page.getRows()) {
            ListUploadVO vo1 = new ListUploadVO();
            vo1.setRightTag(p.getRightTag());
            vo1.setRight("拥有者");
            BeanUtils.copyProperties(p, vo1);
            Integer size = p.getFileSize();
            vo1.setPath(url + p.getFilePath());
            if(size != null){
                vo1.setFileSize(reportService.getPrintSize(size));
            }else {
                vo1.setFileSize(0+"B");
            }
            ReportCollect reportCollect = new ReportCollect();
            reportCollect.setReportId(p.getId());
            List<ReportCollect> reportCollects = collectService.queryByReportId(p.getId(),loginUser.getId());
            if (reportCollects.isEmpty()) {
                vo1.setCollection(2);
            } else {
                vo1.setCollection(1);
            }
            //增加处理状态
            vo1.setStatus("完成");
            if (p.getFileType().equals(3) && null == p.getPdfPath()) { //word类型
                vo1.setStatus("处理中");
            }
            list.add(vo1);
        }
        list = list.stream().sorted((a, b) -> -a.getCreateTime().compareTo(b.getCreateTime())).collect(Collectors.toList());
        pageResult.setRows(list);
        return new ResponseInfo(pageResult);
    }

    @ApiOperation("作者")
    @PostMapping("/create-user")
    public ResponseInfo<List<CountUser>> createUser() {
        List<CountUser> countUsers = privateReportService.countUser();
        return new ResponseInfo(countUsers);
    }

    @ApiOperation("在线查看office文档")
    @RequestMapping(value = "/view-office", method = RequestMethod.GET)
    public ModelAndView viewOffice(HttpServletRequest request, Map<String, Object> map) {
        PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);
        poCtrl.setServerPage("/iir/poserver.zz");//设置服务页面

        poCtrl.setTitlebar(false); // 隐藏标题栏(pageoffice的标题)
        poCtrl.setMenubar(false); // 隐藏菜单栏（文件一个设置）
        poCtrl.setOfficeToolbars(false);// 隐藏Office工具条（word 的编辑按钮）
        poCtrl.addCustomToolButton("全屏切换", "SwitchFullScreen()", 4);
        poCtrl.addCustomToolButton("关闭", "close", 21);

        String type = request.getParameter("type");
        String path = request.getParameter("path");
        if (path.indexOf(minioAddress) >= 0) {
            path = path.substring(minioAddress.length());
        }
        String directory = System.getProperty("java.io.tmpdir");
        String ext = path.substring(path.lastIndexOf('.'));
        String fileName = UUID.randomUUID().toString() + ext;
        File file = new File(directory, fileName);
        fileService.download(path, file);

        if (type.equals("3")) { //word
            poCtrl.webOpen("file://" + directory + File.separator + fileName, OpenModeType.docReadOnly, "张三");
        } else {
            poCtrl.webOpen("file://" + directory + File.separator + fileName, OpenModeType.xlsReadOnly, "张三");
        }
        map.put("pageoffice", poCtrl.getHtmlCode("PageOfficeCtrl1"));

        ModelAndView mv = new ModelAndView("Excel");
        return mv;
    }

    @ApiOperation("在线查看office文档带水印")
    @RequestMapping(value = "/view-office-water", method = RequestMethod.GET)
    public ModelAndView viewOfficeWater(HttpServletRequest request, Map<String, Object> map) {
        try {
            PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);
            poCtrl.setServerPage("/iir/poserver.zz");//设置服务页面

            poCtrl.setTitlebar(false); // 隐藏标题栏(pageoffice的标题)
            poCtrl.setMenubar(false); // 隐藏菜单栏（文件一个设置）
            poCtrl.setOfficeToolbars(false);// 隐藏Office工具条（word 的编辑按钮）
            poCtrl.addCustomToolButton("全屏切换", "SwitchFullScreen()", 4);
            poCtrl.addCustomToolButton("关闭", "close", 21);

            //String type = request.getParameter("type");
            String path = request.getParameter("path");
            if (path.indexOf(minioAddress) >= 0) {
                path = path.substring(minioAddress.length());
            }
            String directory = System.getProperty("java.io.tmpdir");
            String ext = path.substring(path.lastIndexOf('.'));
            String fileName = UUID.randomUUID().toString() + ext;
            File file = new File(directory, fileName);
            fileService.download(path, file);

            User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
            String waterMark = loginUser.getName() + " " + DateUtils.toString(new Date(), "yyyyMMdd");
            String fileName2 = UUID.randomUUID().toString() + ext;
            FileUtils.waterMarkExcel(directory + File.separator + fileName, directory + File.separator + fileName2, waterMark);

            poCtrl.webOpen("file://" + directory + File.separator + fileName2, OpenModeType.xlsReadOnly, "张三");

            map.put("pageoffice", poCtrl.getHtmlCode("PageOfficeCtrl1"));
        } catch (Exception e) {
            log.error("viewOfficeWater错误：", e);
        }

        ModelAndView mv = new ModelAndView("Excel");
        return mv;
    }

    /**
     * 添加PageOffice的服务器端授权程序Servlet（必须）
     *
     * @return
     */
    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        com.zhuozhengsoft.pageoffice.poserver.Server poserver = new com.zhuozhengsoft.pageoffice.poserver.Server();
        poserver.setSysPath(poSysPath);//设置PageOffice注册成功后,license.lic文件存放的目录
        ServletRegistrationBean srb = new ServletRegistrationBean(poserver);
        srb.addUrlMappings("/poserver.zz");
        srb.addUrlMappings("/posetup.exe");
        srb.addUrlMappings("/pageoffice.js");
        srb.addUrlMappings("/jquery.min.js");
        srb.addUrlMappings("/pobstyle.css");
        srb.addUrlMappings("/sealsetup.exe");

        return srb;//
    }

}
